﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Tzync
{
    /*****************************************************************************************************/
    /* Class corresponds to information of one File/Directory in the File System tree stored in logFile. */
    /*****************************************************************************************************/

    public class TreeNode
    {
        //Data Members of Class TreeNode
        private int id;
        private String fullPathA;
        private String fullPathB;
        private String Name;
        private Pair<int, int> versionA;
        private long sizeA;
        private Pair<int, int> versionB;
        private long sizeB;
        private DateTime syncA;
        private DateTime syncB;
        private int parent;
        private List<int> childs;
        private Type type;
        public List<int> dynamicChildList;

        //Constructor
        public TreeNode()
        {
            versionA = new Pair<int, int>();
            versionB = new Pair<int, int>();
            childs = new List<int>();
            dynamicChildList = new List<int>();
        }


        //Overloaded Constructor to initialise the values of the node from the string input        
        //Post-Conditions: Node information is filled from the content of the string input.

        public TreeNode(String input)
        {
            String[] arrWords, arrPair, arrAddress;
            arrWords = input.Split('|');

            //MetaDataEntryValidator(input);

            id = Convert.ToInt32(arrWords[0]);
            fullPathA = arrWords[1];
            arrAddress = fullPathA.Split('\\');
            Name = arrAddress[arrAddress.Count() - 1];
            fullPathB = arrWords[2];
            if (Name == "")
            {
                arrAddress = fullPathB.Split('\\');
                Name = arrAddress[arrAddress.Count() - 1];
            }
            arrPair = arrWords[3].Split(',');
            versionA = new Pair<int, int>(Convert.ToInt32(arrPair[0]), Convert.ToInt32(arrPair[1]));
            sizeA = long.Parse(arrWords[4]);
            arrPair = arrWords[5].Split(',');
            versionB = new Pair<int, int>(Convert.ToInt32(arrPair[0]), Convert.ToInt32(arrPair[1]));
            sizeB = long.Parse(arrWords[6]);
            DateTime parseddt = DateTime.Parse(arrWords[7]);
            DateTimeParser dtp = new DateTimeParser(parseddt);
            syncA = dtp.GetNewDateTime();
            syncB = new DateTimeParser(DateTime.Parse(arrWords[8])).GetNewDateTime();
            parent = Convert.ToInt32(arrWords[9]);

            //Storing the children if the Tree Node is a Directory
            //The list of Children is appended by -1 ALWAYS

            if (arrWords[10].Length > 0) //Folder
            {
                String[] arrChild = arrWords[10].Split(',');
                childs = new List<int>();
                dynamicChildList = new List<int>();
                arrChild = arrWords[10].Split(',');
                foreach (String s in arrChild)
                {
                    childs.Add(Convert.ToInt32(s));
                }
                type = Type.Folder;
            }
            else //File
            {
                childs = null;
                type = Type.File;
            }
        }


        /*********************************************************/
        /* Accessory Functions for the data members of the class */
        /*********************************************************/

        public int getId()
        {
            return id;
        }

        public String getFullPathA()
        {
            return fullPathA;
        }

        public void setFullPathA(String path)
        {
            fullPathA = path;
        }

        public String getFullPathB()
        {
            return fullPathB;
        }

        public void setFullPathB(String path)
        {
            fullPathB = path;
        }

        public String getName()
        {
            return Name;
        }

        public void setName(String path)
        {
            Name = path;
        }

        public Pair<int, int> getVersionA()
        {
            return versionA;
        }

        public void setVersionA(Pair<int, int> p)
        {
            versionA = p;
        }

        public long getSizeA()
        {
            return sizeA;
        }

        public void setSizeA(long size)
        {
            sizeA = size;
        }

        public Pair<int, int> getVersionB()
        {
            return versionB;
        }

        public void setVersionB(Pair<int, int> p)
        {
            versionB = p;
        }

        public long getSizeB()
        {
            return sizeB;
        }

        public void setSizeB(long size)
        {
            sizeB = size;
        }

        public DateTime getSyncA()
        {
            return syncA;
        }
        public void setSyncA(DateTime timestamp)
        {
            syncA = timestamp;
        }

        public DateTime getSyncB()
        {
            return syncB;
        }
        public void setSyncB(DateTime timestamp)
        {
            syncB = timestamp;
        }

        public int getParent()
        {
            return parent;
        }
        public void setParent(int p)
        {
            parent = p;
        }

        public List<int> getChilds()
        {
            return childs;
        }

        public void setChilds(List<int> list)
        {
            childs = list;
        }

        public Type getType()
        {
            return type;
        }

        public void setType(Type t)
        {
            type = t;
        }

        public void addChild(int child)
        {
            dynamicChildList.Add(child);
        }

        public void pushChild(int c, int k)
        {
            childs.Insert(k, c);
        }

        public void RemoveChild(TreeNode child)
        {
            childs.Remove(child.getId());
        }

        /**************************************************************/
        /* Accessory Functions for the data members of the class end !*/
        /**************************************************************/

        //Function to convert the Node information into String 

        public String toString()
        {
            String str = "";
            str = id + "|";
            str += fullPathA + "|";
            str += fullPathB + "|";
            str += versionA.First + "," + versionA.Second + "|";
            str += sizeA + "|";
            str += versionB.First + "," + versionB.Second + "|";
            str += sizeB + "|";
            str += syncA + "|";
            str += syncB;
            str += "|";
            str += parent.ToString();
            str += "|";
            if (childs != null)
            {
                for (int s = 0; s < childs.Count(); s++)
                {
                    str += childs[s];
                    if (s != childs.Count() - 1) str += ',';
                }
            }
            str += "\n";
            return str;
        }

    }

    /*************************************************************************************************************************************/
    /* Class to store time stamp in our preferred way to avoid mis-interpretations due to different representations in different systems */
    /*************************************************************************************************************************************/

    public class DateTimeParser
    {
        private DateTime newDateTime;

        //Constructor to initialise the local Date Time object                 
        //Post-Conditions: Local DateTime object is initialised with dt values in our preferred way.

        public DateTimeParser(DateTime dt)
        {
            DateTime date1 = dt;
            newDateTime = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
        }

        public DateTime GetNewDateTime()
        {
            return newDateTime;
        }
    }

    /***********************/
    /* Class TreeNode ends */
    /***********************/
}
